<?php

/**
 * Created by WuYanzu.
 * Author WuYanzu <9258405@qq.com>
 * Date 2022/1/6 14:21
 */

/**
 * @property ZBlogPHP $zbp 全局类
 * @property BasePost $article 文章类
 * @property string $imageUrl 图片URL
 * @property array $handleFiled 需要处理的字段
 * @property array $imageSuffix 支持的文件后缀
 *
 */
class CnwyzImageLocal
{
    private $article;
    private $zbp;
    private $imageUrl;
    private $handleFiled;
    private $imageSuffix;

    public function __construct($article)
    {
        $this->article     = $article;
        $this->zbp         = $this->zbpInstance();
        $this->handleFiled = $this->definitionHandleFiled();
        $this->imageSuffix = $this->definitionImageSuffix();
        $this->imageUrl    = $this->getImageUrl();
    }

    /**
     * 处理图片本地化
     * Created by WuYanzu.
     * Author WuYanzu <9258405@qq.com>
     * Date 2022/1/6 14:38
     */
    public function handleImageLocal()
    {
        //定义需要处理的字段
        $handleFieldArray = $this->handleFiled;
        foreach ($handleFieldArray as $value) {
            $tmpFiled              = $this->article->$value;
            $this->article->$value = $this->handleFieldImageUrl($tmpFiled);
        }
        $this->article->Save();
    }

    /**
     * 定义需要处理的字段
     * Created by WuYanzu.
     * Author WuYanzu <9258405@qq.com>
     * Date 2022/1/6 14:47
     * @return array
     */
    private function definitionHandleFiled()
    {
        return ['Intro', 'Content'];
    }

    /**
     * 定义图片后缀数组
     * Created by WuYanzu.
     * Author WuYanzu <9258405@qq.com>
     * Date 2022/1/6 14:59
     * @return array
     */
    private function definitionImageSuffix()
    {
        return ['jpg', 'gif', 'png', 'jpeg', 'bmp', 'webp', 'psd', 'wmf', 'ico'];
    }

    /**
     * 获取图片的域名
     * Created by WuYanzu.
     * Author WuYanzu <9258405@qq.com>
     * Date 2022/1/6 15:15
     * @return string|null
     */
    private function getImageUrl()
    {
        $url= $this->zbp->Config('CNWYZImageLocal')->cdnUrl?: $this->zbp->host;
        return $url;
    }

    /**
     * 获取全局ZBP方法
     * Created by WuYanzu.
     * Author WuYanzu <9258405@qq.com>
     * Date 2022/1/6 14:24
     * @return ZBlogPHP|null
     * @throws Exception
     */
    private function zbpInstance()
    {
        $zbp = ZBlogPHP::GetInstance();
        $zbp->Initialize();
        $zbp->Load();
        return $zbp;
    }

    /**
     * 处理字段图片URL
     * Created by WuYanzu.
     * Author WuYanzu <9258405@qq.com>
     * Date 2022/1/6 14:55
     * @param $text [字段内容]
     * @return array|mixed|string|string[]
     */
    private function handleFieldImageUrl($text)
    {
        $tmpArray = $this->handleMatchImageUrlArray($text);
        if (!empty($tmpArray)) {
            foreach ($tmpArray as $value) {
                //需要判断是不是自己的链接 只有当不是自己的连接才会处理
                if ($value == "" || $this->checkFilterUrl($value)) {
                    continue;
                }
                $suffix = $this->getImageSuffix($value);
                if ($suffix == "") { //当无法获取URL 类型时
                    //未获取到后缀
                    continue;
                }
                $suffix       = strtolower(trim($suffix)); //将后缀改为小写
                $times        = time(); //固定时间
                $fileName     = date("YmdHis", $times) . $times . rand(10000, 99999) . '.' . $suffix;
                $fileSavePath = $this->getSaveFileDir($times, $fileName);
                if (!$this->handleDownloadImage($value, $times, $suffix, $fileName, $fileSavePath)) {
                    //处理失败
                    continue;
                }
                $url = str_replace($this->zbp->path, $this->imageUrl, $fileSavePath);
                if ($url != $value && $url) { //有可能有的连接有防盗链 没办法处理 没办法处理的话就没有替换 只有当处理过的才会替换
                    $text = str_replace($value, $url, $text);
                }
            }
        }
        return $text;
    }

    /**
     * 下载URL文件并返回处理过的URL
     * Created by WuYanzu.
     * Author WuYanzu <9258405@qq.com>
     * Date 2022/1/6 16:38
     * @param $url [原始链接]
     * @param $times [时间戳 固定]
     * @param $suffix [后缀]
     * @param $fileName [文件名称]
     * @param $fileSavePath [文件绝对路径]
     * @return bool
     */
    private function handleDownloadImage($url, $times, $suffix, $fileName, $fileSavePath)
    {
        try {

            //下载附件流
            $img = GetHttpContent($url);
            if (!$img) {
                throw new Exception("下载图片失败");
            }
            $upload             = new \Upload();
            $upload->Name       = $fileName;
            $upload->SourceName = $fileName;
            $upload->MimeType   = "image/" . $suffix;
            $upload->Size       = strlen($img);
            $upload->AuthorID   = $this->zbp->user->ID;
            //检测Upload类是否合格
            if ($this->checkImageEligibility($upload, $times) != true) {
                throw new Exception("检测不合格");
            }
            //检测无误之后再储存 避免无用储存
            $fp2 = @fopen($fileSavePath, "a");
            fwrite($fp2, $img);
            fclose($fp2);


            //兼容其他插件上传[Filter_Plugin_Upload_SaveFile]接口
            foreach ($GLOBALS['hooks']['Filter_Plugin_Upload_SaveFile'] as $fpname => &$fpsignal) {
                $fpreturn = $fpname($fileSavePath, $upload);
                if ($fpsignal == PLUGIN_EXITSIGNAL_RETURN) {
                    $fpsignal = PLUGIN_EXITSIGNAL_NONE;
                    return $fpreturn;
                }
            }

            $upload->Save();
            $this->zbp->AddCache($upload);
            return true;
        } catch (Exception $e) {
            return false;
        }
    }


    /**
     * 根据时间处理相应的路径
     * Created by WuYanzu.
     * Author WuYanzu <9258405@qq.com>
     * Date 2022/1/6 15:20
     * @param $times [ 时间]
     * @param $fileName [ 文件名称]
     * @return string 返回一个完整的路径地址
     */
    private function getSaveFileDir($times, $fileName)
    {
        $fileDirPath = $this->zbp->usersdir . 'upload/' . date('Y', $times) . '/' . date('m', $times);
        if (!file_exists($fileDirPath)) {
            @mkdir($fileDirPath, 0755, true);
        }
        return $fileDirPath . "/" . $fileName;
    }

    /**
     * 校验上传类图片数据是否合格
     * Created by WuYanzu.
     * Author WuYanzu <9258405@qq.com>
     * Date 2022/1/6 15:08
     * @param Upload $upload
     * @param int $times
     * @return bool
     */
    private function checkImageEligibility($upload, $times)
    {
        try {
            //检查同月重名
            $d1  = date('Y-m-01', $times);
            $d2  = date('Y-m-d', strtotime(date('Y-m-01', $times) . ' +1 month -1 day'));
            $d1  = strtotime($d1);
            $d2  = strtotime($d2);
            $w   = [];
            $w[] = ['=', 'ul_Name', $upload->Name];
            $w[] = ['>=', 'ul_PostTime', $d1];
            $w[] = ['<=', 'ul_PostTime', $d2];

            $uploads = $this->zbp->GetUploadList('*', $w);
            if (count($uploads) > 0) {
                throw new Exception("存在同名文件");
            }
            if (!$upload->CheckExtName()) {
                throw new Exception("文件类型超出设定范围");
            }
            if (!$upload->CheckSize()) {
                throw new Exception("文件大小超出设定范围");
            }
            return true;
        } catch (Exception $e) {
            return false;
        }
    }

    /**
     * 根据URL 获取后缀是否在里面
     * Created by WuYanzu.
     * Author WuYanzu <9258405@qq.com>
     * Date 2022/1/6 14:56
     * @param $url
     * @return string
     */
    private function getImageSuffix($url)
    {
        $imageSuffix = $this->imageSuffix;
        $suffix      = "";
        foreach ($imageSuffix as $value) {
            if (stristr($url, $value)) {
                $suffix = $value;
                break;
            }
        }
        return $suffix;
    }

    /**
     * 根据内容 正则匹配所有的URL
     * Created by WuYanzu.
     * Author WuYanzu <9258405@qq.com>
     * Date 2022/1/6 14:42
     * @param $text [内容]
     * @return array|mixed
     */
    private function handleMatchImageUrlArray($text)
    {
        $preg = '/<img[^>]*src="([^"]+)"[^>]*>/i';//匹配img标签的正则表达式
        preg_match_all($preg, $text, $allImg);//这里匹配所有的img
        $tmpImage = $allImg[1];
        return $tmpImage ? array_unique($tmpImage) : [];
    }

    /**
     * 验证是否存在过滤的URL中
     * Created by WuYanzu.
     * Author WuYanzu <9258405@qq.com>
     * Date 2022/1/6 17:42
     * @param $url
     * @return bool
     */
    private function checkFilterUrl($url)
    {
        $config      = $this->zbp->Config('CNWYZImageLocal')->filterUrl;
        $configStr   = $config ?: "";
        $configArray = array_filter(explode(',', $configStr));
        array_push($configArray,$this->imageUrl);
        foreach ($configArray as $value){
            if(stristr($url, $value)){
                return true;
            }
        }
        return false;
    }
}